#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "common.h"
extern "C"{
    #include "temu.h"
}
#define REG_NUMBER 32

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //init reg table
    init_reg();
    this->setWindowTitle("~TEMU~");
    file_name = nullptr;
}

void MainWindow::init_reg(){
    //column number
    ui->reg_table->setColumnCount(2);
    ui->special_reg->setColumnCount(2);
    ui->reg_table->setRowCount(REG_NUMBER);
    ui->special_reg->setRowCount(3);
    //auto strecth
    ui->reg_table->horizontalHeader()->setStretchLastSection(true);
    ui->special_reg->horizontalHeader()->setStretchLastSection(true);
    //read only
    ui->reg_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->special_reg->setEditTriggers(QAbstractItemView::NoEditTriggers);
    // no head number
    QHeaderView *headerView = ui->reg_table->verticalHeader();
    headerView -> setHidden(true);
    QHeaderView *headerView1 = ui->special_reg->verticalHeader();
    headerView1 -> setHidden(true);
    //set headers
    QStringList headers;
    headers<<"reg"<<"Value";
    ui->reg_table->setHorizontalHeaderLabels(headers);
    ui->special_reg->setHorizontalHeaderLabels(headers);

    for (int i = 0; i < REG_NUMBER ; i++ ) {
        QString reg_name = regfile[i];
        QTableWidgetItem *item1 = new QTableWidgetItem(reg_name);
        ui->reg_table->setItem(i,0,item1);
        QTableWidgetItem *item2 = new QTableWidgetItem("NAN");
        ui->reg_table->setItem(i,1,item2);
    }
    const char* a[3] = {"$PC","$HI","$LO"};
    for (int i = 0; i < 3 ; i++ ) {
        QString reg_name = a[i];
        QTableWidgetItem *item1 = new QTableWidgetItem(reg_name);
        ui->special_reg->setItem(i,0,item1);
        QTableWidgetItem *item2 = new QTableWidgetItem("NAN");
        ui->special_reg->setItem(i,1,item2);
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::helloworld(){
    ui->result_list->append("=====================");
    ui->result_list->append("Welcome to temu ");
    qDebug() << get_pc() ;
    QString pcinfo = QString::asprintf("Now PC = 0x %08x ",get_pc()).toUpper();
    ui->result_list->append(pcinfo);
    ui->result_list->append("=====================");
}

void MainWindow::flush_reg(){
    for(int i = 0 ; i < REG_NUMBER; i++){
        if(temu_state == END){
            (ui->reg_table->item(i,1))->setText("TEMU END");
        }
        else{
             QString value = QString::asprintf("0x %08x ",cpu.gpr[i]._32).toUpper();
            (ui->reg_table->item(i,1))->setText(value);
        }
    }
    if(temu_state == END){
        ui->special_reg->item(0,1)->setText("TEMU END");
        ui->special_reg->item(1,1)->setText("TEMU END");
        ui->special_reg->item(2,1)->setText("TEMU END");
    }
    else{
        ui->special_reg->item(0,1)->setText(QString::asprintf("0x %08x ",cpu.pc).toUpper());
        ui->special_reg->item(1,1)->setText(QString::asprintf("0x %08x ",cpu.hi).toUpper());
        ui->special_reg->item(2,1)->setText(QString::asprintf("0x %08x ",cpu.lo).toUpper());
    }
}

void MainWindow::step_exec(){
    if(temu_state == END){
        ui->result_list->append("TEMU END");
        return;
    }
    step();
    ui->result_list->append(asm_buf);
    flush_reg();
}

void MainWindow::on_step_exec_clicked()
{
    step_exec();
}


void MainWindow::on_continue_2_clicked()
{
    while(temu_state != END){
        step_exec();
    }
    ui->result_list->append("TEMU END");
}


void MainWindow::on_expr_editingFinished()
{
    if(!expr_init){
       ui->expr_result->setText("No Init");
       return;
    }
    char expr_temp[100] = "NULL";
    QString A = ui->expr->text();
    Qstringtochar(&A , expr_temp);
    bool success = true;
    uint32_t result = expr(expr_temp,&success);
    if(!(success)){
        ui->expr_result->setText("Bad Expr");
        return;
    }
    char result_str[100];
    sprintf(result_str,"%u",result);
    ui->expr_result->setText(result_str);
}


void MainWindow::on_menu_file_triggered()
{
    const QString caption = "选择一个文件";
    const QString dir = "/home/zzzzz/";
    const QString filter = "bin(*.bin)";
    file_name = QFileDialog::getOpenFileName(this,caption,dir,filter);
    QByteArray temp = file_name.toLatin1();
    strcpy(inst_file_path,temp.data());
    temu_state = END;
    qDebug() << "file name = "<< file_name;
    qDebug() << "AFTER: inst = " << inst_file_path;
}


void MainWindow::on_menu_start_triggered()
{
    if(file_name == nullptr){
        ui->result_list->append("can not open file");
        return;
    }
    ui->result_list->append(file_name);
    launch();
}

void MainWindow::launch(){
    launch_temu();
    helloworld();
    flush_reg();
}

void MainWindow::on_menu_clear_triggered()
{
    ui->result_list->clear();
}


void MainWindow::on_watch_expr_editingFinished()
{
    if((!wp_init)|(!expr_init)){
       ui->watch_expr->setText("No Init");
       return;
    }
    char watch_temp[100] = "NULL";
    QString A = ui->watch_expr->text();
    Qstringtochar(&A , watch_temp);
    cmd_w(watch_temp);
    flush_watch();
}

void MainWindow::Qstringtochar(QString *qstring, char *reschar){
    QByteArray temp = (*qstring).toLatin1();
    strcpy(reschar,temp.data());
}

void MainWindow::flush_watch(){

}
